package com.h3bpm.web.service.impl;

import OThinker.Common.Data.Database.Parameter;
import OThinker.Common.Data.DbType;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.h3bpm.web.service.ExpensesOrReceiptsService;
import com.h3bpm.web.utils.DateUtils;
import com.h3bpm.web.utils.HttpClientUtils;
import data.DataException;
import data.DataRow;
import data.DataRowCollection;
import data.DataTable;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import static OThinker.H3.Controller.ControllerBase.getEngine;
import static com.h3bpm.web.utils.DateUtils.timeCompare;

/**
 * @author leo
 */
@Service
public class ExpensesOrReceiptsServiceImpl implements ExpensesOrReceiptsService {
    private static final Logger logger = LoggerFactory.getLogger(ExpensesOrReceiptsServiceImpl.class);

    private static final String sellOrder = "销售类";

    private static final String PurchaseOrder = "采购类";

    @Override
    public Boolean setOrderInfo(String contractNumber, String contractName, String contractNature, String objectId) throws Exception {
        String sql = "SELECT b.orderNumber as orderNumber from i_setcollectionorderno a ,i_orderinfor b WHERE a.objectID = b.ParentObjectID and a.objectID= ?";
        Parameter[] params = new Parameter[1];
        params[0] = new Parameter("objectId", DbType.String, objectId);
        DataTable queryDataTable = getEngine().getPortalQuery().QueryTable(sql, params);
        DataRowCollection queryRows = queryDataTable.getRows();
        HashMap<String, Object> masterData = getMasterData(contractNumber);
        BigDecimal actualPayment = new BigDecimal(0);
        String bigPayDate = null;
        String endDate = null;
        if (masterData.get("actualPayment") != null) {
            actualPayment = (BigDecimal) masterData.get("actualPayment");
        }
        if (masterData.get("performanceTime") != null) {
            bigPayDate = (String) masterData.get("performanceTime");
        }
        if (masterData.get("endDate") != null) {
            endDate = (String) masterData.get("endDate");
        }
        String orderType;
        if ("收入".equals(contractNature)){
            orderType="销售合同";
        }else {
            orderType="采购合同";
        }
        if (queryRows != null && queryRows.size() > 0) {
            analysisReturn(queryRows,contractNumber,contractName,orderType,bigPayDate,actualPayment,endDate);
            return true;
        }
        System.out.println("没有查到订单数据");
        return false;
    }

    @Override
    public Boolean setMasterDataByCredential(String contractNumber, BigDecimal actualPayment, String performanceTime) throws Exception {
        HashMap<String, Object> masterData = getMasterData(contractNumber);
        String bigPayDate = null;
        String endDate = null;
        if (masterData.get("actualPayment") != null) {
            BigDecimal Payment = (BigDecimal) masterData.get("actualPayment");
            actualPayment = actualPayment.add(Payment);
        }
        if (masterData.get("endDate") != null) {
            endDate = (String) masterData.get("endDate");
        }
        if (masterData.get("performanceTime") != null) {
            bigPayDate = (String) masterData.get("performanceTime");
            // 比较最晚付款时间
            boolean bool = timeCompare(bigPayDate, performanceTime);
            if (bool) {
                performanceTime = bigPayDate;
            }
        }

        return setOrderInfoToMasterData(actualPayment, performanceTime, contractNumber,endDate);
    }

    @Override
    public Boolean removeOrderInfo(String contractNumber) {
        String orderSql = "DELETE  FROM i_orderinfor WHERE ParentObjectID in (SELECT ObjectID from i_setcollectionorderno WHERE contractNumber=?)";
        String credentialSql = "DELETE  FROM i_credentialinfor WHERE ParentObjectID in(SELECT ObjectID from i_setcollectionorderno WHERE contractNumber=?)";
        String orderNoSql = "DELETE  FROM i_setcollectionorderno WHERE contractNumber =?";
        String updateSql = "update i_contractdata set actualPayment = 0,performanceTime= null WHERE contractNum = ?";
        Parameter[] params = new Parameter[1];
        params[0] = new Parameter("objectId", DbType.String, contractNumber);
        try {
            int i1 = getEngine().getPortalQuery().ExcuteNoQuery(orderSql, params);
            int i2 = getEngine().getPortalQuery().ExcuteNoQuery(credentialSql, params);
            int i3 = getEngine().getPortalQuery().ExcuteNoQuery(orderNoSql, params);
            int i4 = getEngine().getPortalQuery().ExcuteNoQuery(updateSql, params);
            logger.info("删除订单信息，执行成功");
        } catch (Exception e) {
            logger.info("删除订单信息，执行是失败");
            e.printStackTrace();
            return false;
        }
        return true;
    }


    /**
     * 拉取主数据的合同总金额和付款时间
     * @param contractNumber
     * @return
     * @throws Exception
     */
    private HashMap<String, Object> getMasterData(String contractNumber) throws Exception {
        String getSql = "SELECT actualPayment,performanceTime,endDate from i_contractdata where contractNum = ?";
        Parameter[] getParams = new Parameter[1];
        getParams[0] = new Parameter("contractNum", DbType.String, contractNumber);
        DataTable queryDataTable = getEngine().getPortalQuery().QueryTable(getSql, getParams);
        DataRowCollection queryRows = queryDataTable.getRows();
        HashMap<String, Object> stringObjectHashMap = new HashMap<>(2);
        if (queryRows != null && queryRows.size() > 0) {
            DataRow dataRow = queryRows.get(0);
            BigDecimal actualPayment = dataRow.getBigDecimal("actualPayment");
            String performanceTime = dataRow.getString("performanceTime");
            String endDate = dataRow.getString("endDate");
            stringObjectHashMap.put("actualPayment", actualPayment);
            stringObjectHashMap.put("perfoendDatermanceTime", performanceTime);
            stringObjectHashMap.put("", endDate);
            logger.info("合同主数据现有合同总金额 ：  "+actualPayment);
            logger.info("合同主数据现有合同履行时间 ：  "+performanceTime);
        }
        return stringObjectHashMap;
    }

    /**
     * 更新主数据的合同总金额和最晚的履行时间
     * @param actualPayment
     * @param bigPayDate
     * @param contractNumber
     * @return
     * @throws Exception
     */
    private Boolean setOrderInfoToMasterData(BigDecimal actualPayment, String bigPayDate, String contractNumber,String endDate) throws Exception {
        boolean b = checkBeOverdue(bigPayDate, endDate, contractNumber);
        if (!b){
            return false;
        }
        String updateSql = "update i_contractdata set actualPayment = ?,performanceTime=? WHERE contractNum = ?";
        Parameter[] params2 = new Parameter[3];
        params2[0] = new Parameter("actualPayment", DbType.String, actualPayment.toString());
        params2[1] = new Parameter("performanceTime", DbType.DateTime, bigPayDate);
        params2[2] = new Parameter("contractNum", DbType.String, contractNumber);
        int i = getEngine().getPortalQuery().ExcuteNoQuery(updateSql, params2);
        if (i != 1) {
            logger.info("更新主数据 合同总金额和最晚的履行时间，执行失败");
            return false;
        }
        logger.info("更新主数据 合同总金额和最晚的履行时间，执行成功");
        return true;
    }
    private boolean checkBeOverdue(String bigPayDate,String endDate,String contractNumber) throws Exception {
        boolean bool = timeCompare(bigPayDate, endDate);
        String overdue = "否";
        if (!bool) {
            overdue = "是";
        }
        String updateSql = "update i_contractdata set Overdue = ? WHERE contractNum = ?";
        Parameter[] params2 = new Parameter[2];
        params2[0] = new Parameter("Overdue", DbType.String, overdue);
        params2[1] = new Parameter("contractNum", DbType.String, contractNumber);
        int i = getEngine().getPortalQuery().ExcuteNoQuery(updateSql, params2);
        if (i != 1) {
            logger.info("更新主数据 是否超时，执行失败");
            return false;
        }
        logger.info("更新主数据 是否超时，执行成功");
        return true;
    }

    /**
     * 插入付款明细
     * @param parameter
     * @return
     * @throws Exception
     */
    private Boolean setOrderInfoToExpenses(Parameter[] parameter) throws Exception {
        String insertSql = "INSERT INTO i_expensesmanagement (`ObjectID`,`contractNumber`, `contractName`, `contractClass`, `groupName`,`itemCode`, `itemName`, `orderAmt`, `orderNumber`, `orderQty`, `vendorCode`, `payDate`, `orderPrice`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?);";
        int i = getEngine().getPortalQuery().ExcuteNoQuery(insertSql, parameter);
        if (i != 1) {
            logger.info("插入付款明细，执行失败");
            throw new Exception("执行失败");
        }
        logger.info("插入付款明细，执行成功");
        return true;
    }

    /**
     * 插入收款明细
     * @param parameter
     * @return
     * @throws Exception
     */
    private Boolean setOrderInfoToReceipts(Parameter[] parameter) throws Exception {
        String insertSql = "INSERT INTO i_receiptsmanagement (`ObjectID`,`contractNumber`, `contractName`, `contractClass`, `groupName`,`itemCode`, `itemName`, `orderAmt`, `orderNumber`, `orderQty`, `vendorCode`, `payDate`, `orderPrice`) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?);";
        int i = getEngine().getPortalQuery().ExcuteNoQuery(insertSql, parameter);
        if (i != 1) {
            logger.info("插入收款明细，执行失败");
            throw new Exception("执行失败");
        }
        logger.info("插入收款明细，执行成功");
        return true;
    }

    /**
     * get类型的接口调用
     *
     * @param orderId
     * @return
     */
    private JSONArray getOrderInfoByOne(String orderId, String orderType) {
        String urlAddr = null;
        if (sellOrder.equals(orderType)) {
            urlAddr = "http://10.50.132.90:8001/omOrder/";
        } else if (PurchaseOrder.equals(orderType)) {
            urlAddr = "http://10.50.132.90:8001/pmOrder/";
        }
        String msg = HttpClientUtils.doGet(urlAddr.concat(orderId));
        logger.info("OrderInfoMsg = {}", msg);
        return JSONArray.parseArray(msg);
    }

    /**
     * 解析全部订单的生成合同已付总金额，最大的履行时间
     * @param queryRows
     * @param contractNumber
     * @param contractName
     * @param orderType
     * @param bigPayDate
     * @param actualPayment
     * @throws Exception
     */
    private void analysisReturn( DataRowCollection queryRows,String contractNumber, String contractName, String orderType, String bigPayDate, BigDecimal actualPayment,String endDate) throws Exception {
        int n = 0;
        for (int i = 0; i < queryRows.size(); i++) {
            DataRow dataRow = queryRows.get(i);
            String orderNumber = dataRow.getString("orderNumber");
            System.out.println("orderNumber:  " + orderNumber);
            logger.info("第 "+i+" 个订单号执行开始，订单号为：  "+orderNumber);
            JSONArray jsonArray = getOrderInfoByOne(orderNumber, orderType);
            if (jsonArray != null && jsonArray.size() > 0) {
                for (int j = 0; j < jsonArray.size(); j++) {
                    String string = jsonArray.getString(j);
                    JSONObject jsonObject = JSON.parseObject(string);
                    Parameter[] dataParams = new Parameter[13];
                    String groupName = jsonObject.getString("groupName");
                    String itemCode = jsonObject.getString("itemCode");
                    String itemName = jsonObject.getString("itemName");
                    String orderAmt = jsonObject.getString("orderAmt");
                    String orderNo = jsonObject.getString("orderNo");
                    String orderQty = jsonObject.getString("orderQty");
                    String vendorCode = jsonObject.getString("vendorCode");
                    String payDate = jsonObject.getString("payDate");
                    String orderPrice = jsonObject.getString("orderPrice");
                    String uuid = UUID.randomUUID().toString();
                    dataParams[0] = new Parameter("ObjectID", DbType.String, uuid);
                    dataParams[1] = new Parameter("contractNumber", DbType.String, contractNumber);
                    dataParams[2] = new Parameter("contractName", DbType.String, contractName);
                    dataParams[3] = new Parameter("contractClass", DbType.String, orderType);
                    dataParams[4] = new Parameter("groupName", DbType.String, groupName);
                    dataParams[5] = new Parameter("itemCode", DbType.String, itemCode);
                    dataParams[6] = new Parameter("itemName", DbType.String, itemName);
                    dataParams[7] = new Parameter("orderAmt", DbType.String, orderAmt);
                    dataParams[8] = new Parameter("orderNumber", DbType.String, orderNo);
                    dataParams[9] = new Parameter("orderQty", DbType.String, orderQty);
                    dataParams[10] = new Parameter("vendorCode", DbType.String, vendorCode);
                    dataParams[11] = new Parameter("payDate", DbType.DateTime, payDate);
                    dataParams[12] = new Parameter("orderPrice", DbType.String, orderPrice);
                    logger.info("单个订单总金额 orderAmt = {}", orderAmt);

                    // 插入收付款订单详情
                    if (sellOrder.equals(orderType)) {
                        setOrderInfoToExpenses(dataParams);
                    } else {
                        setOrderInfoToReceipts(dataParams);
                    }

                    // 比较最晚付款时间
                    // 不为空进行比较，为空不做处理
                    if (StringUtils.isNotEmpty(payDate)) {
                        if (n == 0) {
                            bigPayDate = payDate;
                            n++;
                        }
                        boolean bool = timeCompare(bigPayDate, payDate);
                        if (!bool) {
                            bigPayDate = payDate;
                        }
                        logger.info("bigPayDate = {}", bigPayDate);
                    }
                    // 订单总金额相加
                    if (orderAmt != null) {
                        logger.info("单个订单总金额 orderAmt = {}", orderAmt);
                        BigDecimal bigDecimal = new BigDecimal(orderAmt);
                        logger.info("单个订单总金额转成bigDecimal, orderAmt= {}", bigDecimal);
                        logger.info("之前总金额 actualPayment ={}",actualPayment);
                        actualPayment = bigDecimal.add(actualPayment);
                        logger.info("相加完总金额 actualPayment = {}", actualPayment);
                    }

                }

            }
        }
        logger.info("最终相加完总金额 actualPayment = {}", actualPayment);
        logger.info("最终最晚的付款时间 bigPayDate = {}", bigPayDate);
        setOrderInfoToMasterData(actualPayment, bigPayDate, contractNumber,endDate);
    }
}

